/*
 * process_gps.c
 *
 *  Created on: Mar 19, 2014
 *      Author: lifeng
 */

#include <stdio.h>
#include <unistd.h>

#include <pthread.h>

#include "./serial/frame_manager.h"
#include "./lib/block_manager.h"
#include "./lib/block_filter.h"
#include "./lib/bcd.h"
#include "./led/led.h"

#include "./serial/frame.h"
#include "./lib/hwclock.h"

#include "./state/state.h"
#include "./battery/battery.h"

static pthread_t thread_gps;
const int GPSNOTRECICTTIMEMAX = 8;
static int notReciveTimeCount = 0;

static void * proc_gps(void *args) {

	while (1) {
		if ( notReciveTimeCount < GPSNOTRECICTTIMEMAX ) {
					notReciveTimeCount++;
		} else { //超时

			set_sys_state(BIT3_GPS,STATE_GPS_FAIL);
			set_sys_state(BIT4_GPS_VALID,STATE_GPS_INVALID);
		//	printf("light_gps_alarm(1);\n");
			light_gps_alarm(1);
		}
		sleep(1);
	}
     return NULL;
}

static void process_gps_frame(void *dataSrc, char *data,int len) {

		struct frame sframe;
		struct frame * pframe;
//		int length;
//		char dest_addr = 0;
//		char src_addr = 0;
//		char operation = 0;
//		char cmd = 0;
//		char tmp;
		int i;
//		char buffer[256];
		notReciveTimeCount=0;

		char firstGPS = 1;
		char gpsSate = 0;
		char year, month, day, hour, minute, second;

//		struct tm time;

		set_sys_state(BIT3_GPS,STATE_GPS_OK);

		light_on(GPS_LED);
		light_gps_alarm(0);
		//printf("light_gps_alarm(0);%d\n",notReciveTimeCount);
		for(i=0;i<len;i++)
		{
			sframe.data[i]=data[i];
		}
		sframe.length=len;
	    pframe=&sframe;


		gpsSate = pframe->data[12];
	//	printf("Recive Gps Frame %x\r\n",gpsSate);
		if (gpsSate == (char) 0x41) { //gps time valid
		//	printf("Setting system Time ok\r\n");
			set_sys_state(BIT4_GPS_VALID,STATE_GPS_VALID);
			//clear_sys_bit(0x10);
			//printf("Sysstate:%x\r\n",get_sys_state());
			year = from_bcd(pframe->data[54]);
			month = from_bcd(pframe->data[55]);
			day = from_bcd(pframe->data[56]);
			hour = from_bcd(pframe->data[57]);
			minute = from_bcd(pframe->data[58]);
			second = from_bcd(pframe->data[59]);
			if ((year < 100) && (month < 13) && (day < 32) && (hour < 24)
					&& (minute < 60) && (second < 60)) {
				struct tm tGPS;
				tGPS.tm_year = (2000 - 1900) + year;
				tGPS.tm_mon = month - 1;
				tGPS.tm_mday = day;
				tGPS.tm_hour = hour;
				tGPS.tm_min = minute;
				tGPS.tm_sec = second;
				if (firstGPS) {

					set_time(&tGPS);
					set_time2(&tGPS);
					firstGPS = 0;
				} else {
					struct tm tSys;
					get_time(&tSys);
					if ((tGPS.tm_year != tSys.tm_year)
							|| (tGPS.tm_mon != tSys.tm_mon)
							|| (tGPS.tm_mday != tSys.tm_mday)) {
						set_time(&tGPS);
						set_time2(&tGPS);
					} else {
						int s1 = hour * 60 * 60 + minute * 60 + second;
						int s2 = tSys.tm_hour * 60 * 60 + tSys.tm_min * 60
								+ tSys.tm_sec;
						int diff = s1 < s2 ? (s2 - s1) : (s1 - s2);
						if (diff > 30) {
							set_time(&tGPS);
							set_time2(&tGPS);
						}
					}
				}

			}

		} else if (gpsSate == (char) 0x56) {

			set_sys_state(BIT4_GPS_VALID,STATE_GPS_INVALID);
			//set_sys_bit(0x10);
		}

}

void init_gps_proc() {
	struct frame_manager *manager = get_frame_manager(GPS_MANAGER);
	manager->processHandler = process_gps_frame;


}

void start_gps_process() {
	init_gps_proc();
	pthread_create(&thread_gps, NULL, proc_gps, NULL);
}
